package com.starsky.common.utils.mail;

import com.sun.mail.util.MailSSLSocketFactory;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.security.GeneralSecurityException;
import java.util.Date;
import java.util.List;
import java.util.Properties;

/**
 * @desc: 邮件工具类
 * @author: wangsh
 */
@Slf4j
public class MailUtils {

    private MailUtils() {
    }

    /**
     * 获取示例
     *
     * @return
     */
    public static MailUtils getInstance() {
        return new MailUtils();
    }

    /**
     * 创建session
     *
     * @param host:ip地址或者域名
     * @return
     */
    public static Session getSession(String host) throws GeneralSecurityException {
        return getSession(host, null, null, null, null);
    }

    /**
     * 创建session
     *
     * @param host:ip地址或者域名
     * @param port：端口号
     * @param protocol：协议默认smtp
     * @param auth:是否要求身份认证，默认true
     * @param debug:是否启用调试模式，默认false
     * @return
     */
    public static Session getSession(String host, String port, String protocol, Boolean auth, Boolean debug) throws GeneralSecurityException {
        // 创建请求参数
        Properties props = new Properties();
        // SMTP邮件服务器地址
        props.setProperty("mail.smtp.host", host);
        // SMTP邮件服务器默认端口25
        props.setProperty("mail.smtp.port", StringUtils.isEmpty(port) ? "25" : port);
        //开启ssl认证
        props.put("mail.smtp.ssl.enable", "true");
        MailSSLSocketFactory sf = new MailSSLSocketFactory();
        sf.setTrustAllHosts(true);
        props.put("mail.smtp.ssl.socketFactory", sf);
        // 邮件发送协议 stmp
        props.setProperty("mail.transport.protocol", StringUtils.isEmpty(protocol) ? "smtp" : protocol);
        // 是否要求身份认证
        props.setProperty("mail.smtp.auth", auth == null ? "true" : auth + "");
        // 是否启用调试模式（启用调试模式可打印客户端与服务器交互过程时一问一答的响应消息）
        props.setProperty("mail.debug", debug == null ? "false" : debug + "");
        // 创建Session实例对象
        Session session = Session.getInstance(props, new Authenticator() {
        });

        return session;
    }


    /**
     * 获取发送消息实例
     *
     * @param session
     * @param from：发送人
     * @param to：接收人
     * @param subject：主题
     * @param content：内容
     * @return
     * @throws MessagingException
     */
    private static MimeMessage getMessage(Session session, String from, String to, String subject, String content) throws MessagingException {
        // 创建MimeMessage实例对象
        MimeMessage message = new MimeMessage(session);
        // 设置发送人
        message.setFrom(new InternetAddress(from));
        // 设置发送时间
        message.setSentDate(new Date());
        // 设置邮件主题
        message.setSubject(subject);
        // 设置收件人
        message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
        message.setContent(content, "text/html;charset=utf-8");
        // 保存并生成最终的邮件内容
        message.saveChanges();

        return message;
    }

    /**
     * 发送邮件内容
     *
     * @param dto:       邮件信息
     * @param subject：主题
     * @param content：内容
     * @throws MessagingException
     */
    public static void sendEMail(MailDto dto, String subject, String content) {
        try {
            // 创建Session实例对象
            Session session = getSession(dto.getHost(), dto.getPort(), dto.getProtocol(), dto.getAuth(), dto.getDebug());
            // 创建MimeMessage实例对象
            MimeMessage message = getMessage(session, dto.getFrom(), dto.getTo(), subject, content);
            Transport transport = session.getTransport();
            // 打开连接
            transport.connect(dto.getFrom(), dto.getSecret());
            // 将message对象传递给transport对象，将邮件发送出去
            transport.sendMessage(message, message.getAllRecipients());
            // 关闭连接
            transport.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 发送邮件内容
     *
     * @param session:ip地址或者域名
     * @param from：端口号
     * @param authCode：授权码
     * @param to：协议默认smtp
     * @param subject：主题
     * @param content：内容
     * @throws MessagingException
     */
    public static void sendEMail(Session session, String from, String authCode,
                                 String to, String subject, String content) {
        try {
            // 创建MimeMessage实例对象
            MimeMessage message = new MimeMessage(session);
            // 设置发送人
            message.setFrom(new InternetAddress(from));
            // 设置发送时间
            message.setSentDate(new Date());
            // 设置收件人
            message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
            // 设置邮件主题
            message.setSubject(subject);
            message.setContent(content, "text/html;charset=utf-8");
            // 保存并生成最终的邮件内容
            message.saveChanges();

            Transport transport = session.getTransport();
            // 打开连接
            transport.connect(from, authCode);
            // 将message对象传递给transport对象，将邮件发送出去
            transport.sendMessage(message, message.getAllRecipients());
            // 关闭连接
            transport.close();
        } catch (Exception e) {
            e.getMessage();
        }
    }

    /**
     * 发送邮件
     *
     * @param host：地址
     * @param from:发送邮件人
     * @param authCode：发送邮件授权码
     * @param tos：接收邮件
     * @param subject：主题
     * @param text：发送内容
     */
    public static void sendEmail(String host, String port, String from, String authCode, List<String> tos,
                                 String subject, String text) {
        try {
            //参考地址 https://www.runoob.com/java/java-sending-email.html
            host = StringUtils.isEmpty(from) ? "smtp.qq.com" : host;
            from = StringUtils.isEmpty(from) ? "791768224@qq.com" : from;
            authCode = StringUtils.isEmpty(authCode) ? "tjzksqkmyrtpbeji" : authCode;

            // 获取系统属性
            Properties properties = System.getProperties();
            // SMTP邮件服务器地址
            properties.setProperty("mail.smtp.host", host);
            // SMTP邮件服务器默认端口25
            properties.setProperty("mail.smtp.port", StringUtils.isEmpty(port) ? "25" : port);
            properties.put("mail.smtp.auth", "true");
            properties.put("mail.smtp.ssl.enable", "true");
            MailSSLSocketFactory sf = new MailSSLSocketFactory();
            sf.setTrustAllHosts(false);
            properties.put("mail.smtp.ssl.socketFactory", sf);
            String finalFrom = from;
            String finalAuthCode = authCode;
            Session session = Session.getDefaultInstance(properties, new Authenticator() {
                public PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(finalFrom, finalAuthCode); //授权码
                }
            });

            MimeMessage message = new MimeMessage(session);
            message.setFrom(new InternetAddress(from));
            int size = tos.size();
            Address[] addresses = new InternetAddress[size];
            for (int i = 0; i < size; i++) {
                addresses[i] = new InternetAddress(tos.get(i));
            }
            message.addRecipients(Message.RecipientType.TO, addresses);
            message.setSubject(subject);
            message.setText(text);
            //发送邮件
            Transport.send(message);

        } catch (Exception mex) {
            mex.printStackTrace();
        }
    }

    /**
     * 发送邮件
     *
     * @param host：地址
     * @param from:发送邮件人
     * @param authCode：发送邮件授权码
     * @param tos：接收邮件
     * @param subject：主题
     * @param text：发送内容
     */
    public static void sendEmail(String host, String from, String authCode, List<String> tos,
                                 String subject, String text) {
        try {
            //参考地址 https://www.runoob.com/java/java-sending-email.html
            host = StringUtils.isEmpty(from) ? "smtp.qq.com" : host;
            from = StringUtils.isEmpty(from) ? "791768224@qq.com" : from;
            authCode = StringUtils.isEmpty(authCode) ? "tjzksqkmyrtpbeji" : authCode;

            // 获取系统属性
            Properties properties = System.getProperties();
            properties.setProperty("mail.smtp.host", host);
            properties.put("mail.smtp.auth", "true");
            properties.put("mail.smtp.ssl.enable", "true");
            MailSSLSocketFactory sf = new MailSSLSocketFactory();
            sf.setTrustAllHosts(true);
            properties.put("mail.smtp.ssl.socketFactory", sf);
            String finalFrom = from;
            String finalAuthCode = authCode;
            Session session = Session.getDefaultInstance(properties, new Authenticator() {
                public PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(finalFrom, finalAuthCode); //授权码
                }
            });

            MimeMessage message = new MimeMessage(session);
            message.setFrom(new InternetAddress(from));
            int size = tos.size();
            Address[] addresses = new InternetAddress[size];
            for (int i = 0; i < size; i++) {
                addresses[i] = new InternetAddress(tos.get(i));
            }
            message.addRecipients(Message.RecipientType.TO, addresses);
            message.setSubject(subject);
            message.setText(text);
            //发送邮件
            Transport.send(message);

        } catch (Exception mex) {
            mex.printStackTrace();
        }
    }

    public static void main(String[] args) throws Exception {

//        String host = "shouhai.wang@daison-intelligence.com";
//        String port = "465";

        String host = "smtp.qq.com";
        boolean auth = true;
        String from = "791768224@qq.com";
        String password = "tjzksqkmyrtpbeji";
//        String to = "1057718341@qq.com";
        String to = "shouhai.wang@daison-intelligence.com";

        String subject = "测试邮件发送";
        String text = "测试邮件发送";

        // 获取系统属性
//        sendEmail(host, from, password, Arrays.asList(to), subject, text);
//        sendEmail(host, null, from, password, Arrays.asList(to), subject, text);
////
        Session session = getSession(host, null, null, true, false);
        sendEMail(session, from, password, to, subject, text);
    }

}
